﻿/*************************************
 * Creator:SW-PeiYang
 * DateTime:2023/9/13 9:51:36
 * Description:<Description>
 * CopyRight:中广核研究院有限公司
 * ***********************************/

using Cpjit.SunnyPaine.Toolkit.Net.Sockets.Model;
using System;
using System.Net;

namespace Cpjit.SunnyPaine.Toolkit.Net.Sockets.UDP
{
    /// <summary>
    /// UDP通讯。
    /// </summary>
    public interface IUdpClient : ISocket
    {
        #region 公共属性
        /// <summary>
        /// 收到消息后是否自动回复。
        /// </summary>
        bool IsAutoReply { get; set; }
        /// <summary>
        /// 自动回复的内容。
        /// </summary>
        string ReplyContent { get; set; }
        /// <summary>
        /// 本机IP。
        /// </summary>
        string IP { get; }
        /// <summary>
        /// 本机端口。
        /// </summary>
        int Port { get; }

        /// <summary>
        /// 符合 127.0.0.1:8000 标准格式的IP端口地址。
        /// </summary>
        string IPHost { get; }
        /// <summary>
        /// 指示 <see cref="ISocket"/> 的实现是客户端还是服务端。true：客户端。false：服务端。
        /// UDP本质上没有客户端与服务端的概念，该属性用于自定义业务性质。
        /// </summary>
        bool? IsClient { get; }
        /// <summary>
        /// 启用心跳机制。
        /// </summary>
        bool UseHeartbeat { get; set; }
        /// <summary>
        /// 心跳周期。单位：ms。
        /// </summary>
        int HeartbeatInterval { get; set; }
        #endregion


        #region 事件委托
        /// <summary>
        /// 当连接时发生。
        /// </summary>
        event Action<IUdpClient, SessionEventArgs> OnConnected;
        /// <summary>
        /// 当断开连接时发生。
        /// </summary>
        event Action<IUdpClient, SessionEventArgs> OnDisConnected;
        /// <summary>
        /// 当收到消息时发生。
        /// </summary>
        event Action<IUdpClient, SessionEventArgs> OnReceived;
        /// <summary>
        /// 当出现错误时发生。
        /// </summary>
        event Action<IUdpClient, SessionEventArgs, Exception> OnError;
        #endregion


        #region 公共方法
        /// <summary>
        /// 启动UDP通讯
        /// </summary>
        bool Start();

        /// <summary>
        /// 连接到远端UDP。
        /// </summary>
        /// <param name="remoteIP"></param>
        /// <param name="remotePort"></param>
        /// <returns></returns>
        bool Connect(string remoteIP, int remotePort);

        void AddRemote(EndPoint endPoint, string clientId);

        /// <summary>
        /// 停止和释放UDP通讯。作用同 <see cref="IDisposable.Dispose()"/> 方法。
        /// </summary>
        void Stop();

        /// <summary>
        /// （连接远端UDP成功后）发送消息。
        /// </summary>
        /// <param name="message">消息内容。</param>
        void Send(string message);

        /// <summary>
        /// （连接远端UDP成功后）发送消息。
        /// </summary>
        /// <param name="datas">消息数据。</param>
        void Send(byte[] datas);

        /// <summary>
        /// （连接远端UDP成功后）发送消息。
        /// </summary>
        /// <param name="message">消息内容。</param>
        void SendAsync(string message);

        /// <summary>
        /// （连接远端UDP成功后）发送消息。
        /// </summary>
        /// <param name="datas">消息数据。</param>
        void SendAsync(byte[] datas);

        /// <summary>
        /// 发送消息。
        /// </summary>
        /// <param name="message">消息内容。</param>
        /// <param name="ip">目标IP。</param>
        /// <param name="port">目标端口。</param>
        void SendTo(string message, string ip, int port);

        /// <summary>
        /// 发送消息。
        /// </summary>
        /// <param name="datas">消息数据。</param>
        /// <param name="ip">目标IP。</param>
        /// <param name="port">目标端口。</param>
        void SendTo(byte[] datas, string ip, int port);

        /// <summary>
        /// 发送消息。
        /// </summary>
        /// <param name="message">消息内容。</param>
        /// <param name="ip">目标IP。</param>
        /// <param name="port">目标端口。</param>
        void SendToAsync(string message, string ip, int port);

        /// <summary>
        /// 发送消息。
        /// </summary>
        /// <param name="datas">消息数据。</param>
        /// <param name="ip">目标IP。</param>
        /// <param name="port">目标端口。</param>
        void SendToAsync(byte[] datas, string ip, int port);
        #endregion
    }
}
